﻿namespace RS.CmeFastHandler
{
	using System;
	using System.Collections.Generic;
	using System.IO;
	using System.Threading;

	/// <summary>
	/// 多线程安全的Queue
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public class SharedQueue<T>
	{


		// Fields
		protected bool m_isOpen = true;
		protected Queue<T> m_queue = new Queue<T>();





		public void Clear()
		{
			lock (this.m_queue)
			{
				this.m_queue.Clear();
				Monitor.Pulse(this.m_queue);
			}
		}

		// Methods
		public void Close()
		{
			lock (this.m_queue)
			{
				this.m_isOpen = false;
				Monitor.PulseAll(this.m_queue);
			}
		}

		public T Dequeue()
		{
			lock (this.m_queue)
			{
				while (this.m_queue.Count == 0)
				{
					//this.EnsureIsOpen();
					Monitor.Wait(this.m_queue);
				}
				return this.m_queue.Dequeue();
			}
		}

		public bool Dequeue(int millisecondsTimeout, T defaultValue, out T result)
		{
			if (millisecondsTimeout == -1)
			{
				result = this.Dequeue();
				return true;
			}
			DateTime now = DateTime.Now;
			lock (this.m_queue)
			{
				while (this.m_queue.Count == 0)
				{
					this.EnsureIsOpen();
					TimeSpan span = (TimeSpan)(DateTime.Now - now);
					int totalMilliseconds = (int)span.TotalMilliseconds;
					int num2 = millisecondsTimeout - totalMilliseconds;
					if (num2 <= 0)
					{
						result = defaultValue;
						return false;
					}
					Monitor.Wait(this.m_queue, num2);
				}
				result = this.m_queue.Dequeue();
				return true;
			}
		}

		public T DequeueNoWait(T defaultValue)
		{
			lock (this.m_queue)
			{
				if (this.m_queue.Count == 0)
				{
					this.EnsureIsOpen();
					return defaultValue;
				}
				return this.m_queue.Dequeue();
			}
		}

		public void Enqueue(T o)
		{
			lock (this.m_queue)
			{
				//this.EnsureIsOpen();
				this.m_queue.Enqueue(o);
				Monitor.Pulse(this.m_queue);
			}
		}

		public T Peek()
		{
			lock (this.m_queue)
			{
				while (this.m_queue.Count == 0)
				{
					//this.EnsureIsOpen();
					Monitor.Wait(this.m_queue);
				}
				return this.m_queue.Peek();
			}
		}

		private void EnsureIsOpen()
		{
			if (!this.m_isOpen)
			{
				throw new IOException("SharedQueue closed");
			}
		}


	}
}